#ifndef _TERRAIN_SM5_H
#define _TERRAIN_SM5_H

#include "CVirtualTextureManager.h"



	//
	// Terrain Editor interface
	//

	class ITerrainEditor
	{
	public:
		struct TBrush
		{
			CTexturePtr		pTexture;
			e_texture::type	eType;
			///
			TBrush(): pTexture(), eType(e_texture::UNKNOWN) {}
		};

	public:
		virtual void  EnableEditing(uint uLayer) = 0;
		virtual void  DisableEditing() = 0;
		virtual int   GetCurrentLayer() = 0;	// -1 if editing disabled

		// use brush //
		virtual void  DotBrush(const vec3 &vWPos, float fPower) = 0;
		virtual void  RoundBrush(const vec3 &vWPos, float fRadius, float fPower) = 0;
		virtual void  Brush(const TBrush &sBrush, const vec3 &vWPos, float fSize, float fPower) = 0;
	};



	//
	// Terrain interface
	//

	class ITerrain
	{
	public:
		virtual void  Update() = 0;
		virtual void  Render(TCameraRenderQueue *pCRQ) = 0;
		virtual void  GetEditor(ITerrainEditor *&pEditor) = 0;
	};

	

	//
	// Terrain (Shader Model 5)
	//

	class _EXPORT_ CTerrain_sm5 : public ITerrain, public ITerrainEditor, public CEngBaseObject
	{
	protected:
		struct TTerrainData
		{
			vec2	vSize;			// virtual texture size
			float	fGridScale;		// grid coords to world
			float	fHeightScale;	// vtex height map scale
		};

		struct TBrushData
		{
			vec2	vPos;
			float	fRadius;
			float	fAlpha;
		};

		typedef CVirtualTextureManager::index_t		index_t;

	protected:
		CTexture2DPtr			_pHeightNormal;		// height and normal map (RGBA8)
								//_pReserveHN;		// reserved texture to update height and normal map
		CTexture2DPtr			_pVTexCoord;		// virtual texture coord and tess level (RGB16UI)
		array< index_t >		_aTexCoords;		// virtual texture indices
		CMeshPtr				_pGrid;
		CVirtualTextureManager	_cVTex;
		CShaderProgramPtr		_pLod0,
								_pLod0_v1,
								_pLod1;
		TTerrainData			_sTerrainData;
		vec2					_vGridCenter;		// in world space
		uint					_uGridSize;			// grid dimension NxN

	protected:
		static void _s_Draw(void *, void *);

	public:
		CTerrain_sm5();
		~CTerrain_sm5();

		bool Create();
		void Destroy();

		// temp
		void DrawLod0();
		void DrawLod0v1();

		// ITerrain //
		virtual void  Update();
		virtual void  Render(TCameraRenderQueue *pCRQ);
		virtual void  GetEditor(ITerrainEditor *&pEditor);

		// ITerrainEditor //
		virtual void  EnableEditing(uint uLayer) {}
		virtual void  DisableEditing() {}
		virtual int   GetCurrentLayer() { return -1; }
		virtual void  DotBrush(const vec3 &vWPos, float fPower) {}
		virtual void  RoundBrush(const vec3 &vWPos, float fRadius, float fPower) {}
		virtual void  Brush(const TBrush &sBrush, const vec3 &vWPos, float fSize, float fPower) {}

		// CEngBaseObject //
		virtual void  Release();
	};
	

	typedef TAutoPtr< CTerrain_sm5, CEngBaseObject, TAutoPtrStrategy< CEngBaseObject > >	CTerrainPtr;

//-------------------------------------------------------------------

#endif	// _TERRAIN_SM5_H